import Vue from 'vue'

function onInput(el, ele, binding, vnode) {
  function handle() {
    // 只保留数字
    let val = ele.value
    // modifiers为修饰符对象，传入了float，则其float属性为true
    if (binding.modifiers.float) {
      // 清除"数字"和"."以外的字符
      val = val.replace(/[^\d.]/g, '')
      // 只保留第一个, 清除多余的
      val = val.replace(/\.{2,}/g, '.')
      // 第一个字符如果是.号，则补充前缀0
      val = val.replace(/^\./g, '0.')
      if (typeof binding.value !== 'undefined') {
        // 期望保留的最大小数位数
        let pointKeep = 0
        if (typeof binding.value === 'string' ||
          typeof binding.value === 'number') {
          pointKeep = parseInt(binding.value)
        }
        if (!isNaN(pointKeep)) {
          if (!Number.isInteger(pointKeep) ||
            pointKeep < 0) {
            pointKeep = 0
          }
          const str = '^(\\d+)\\.(\\d\{' + pointKeep + '}).*$'
          const reg = new RegExp(str)
          if (pointKeep === 0) {
            // 不需要小数点
            val = val.replace(reg, '$1')
          } else {
            // 通过正则保留小数点后指定的位数
            val = val.replace(reg, '$1.$2')
          }
        }
      }
      if (Number(val) > 10000000) val = 10000000
      ele.value = val + ''
    } else {
      ele.value = ele.value.replace(/[\D]/g, '')
    }
    // 当输入汉字时会导致vue model 数据不同步，因此在回调函数添加上以下代码，手动触发数据的双向绑定。
    if (vnode.componentInstance) {
      vnode.componentInstance.$emit('input', ele.value)
    } else {
      // 移动端可能不支持 CustomEvent. 下面是兼容方法
      // function CustomEvent(event, params) {
      //   params = params || { bubbles: false, cancelable: false, detail: undefined };
      //   var evt = document.createEvent('CustomEvent');
      //   evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
      //   return evt;
      // };
      // CustomEvent.prototype = window.Event.prototype;
      vnode.elm.dispatchEvent(new CustomEvent('input', ele.value))
    }
  }
  return handle
}
const numberInput = {
  bind(el, binding, vnode) {
    const ele = el.tagName === 'INPUT' ? el : el.querySelector('input')
    ele.addEventListener('keyup', onInput(el, ele, binding, vnode), false)
  }
}
Vue.directive('number-input', numberInput)
